package com.hsh.acte
{
	import com.hsh.graph.Etat;
	import com.hsh.graph.Visuel;
	import flash.display.DisplayObject;
	import flash.display.DisplayObjectContainer;
	import flash.display.InteractiveObject;
	import flash.filters.DropShadowFilter;
	import flash.filters.GradientBevelFilter;
	import flash.geom.Rectangle;
	
	/**
	 * Elément affichable
	 * @author Jean-Marie@home
	 */
	public class Actif
	{
		private var ed:InteractiveObject;
		private var actions:Vector.<Action> = new Vector.<Action>;
		private var _pere:Visuel
		protected var _etat:Etat;
		protected var _largeur:Number = 0.0;
		protected var _hauteur:Number = 0.0;
		
		public function Actif(diffuseur:InteractiveObject, idActif:String)
		{
			ed = diffuseur;
			id = idActif;
		}
		
		public function actualiser():void
		{
			// force l'affichage. Overrider
		}
		
		public function contient(a:Actif):Boolean
		{
			return rectScene.containsRect(a.rectScene);
		}
		
		/**
		 * Définit la position du centre du visuel
		 * @param	x	centre horizontal du visuel
		 * @param	y	centre vertical du visuel
		 */
		public function centrer(x:Number, y:Number):void
		{
			centreX = x;
			centreY = y;
		}
		
		/**
		 * a. Fermeture des écouteurs b. Suppression de la liste d'affichage
		 * c. Annulation des valeurs _etat, _largeur, _hauteur, ed.
		 */
		public function detruire():void
		{
			while (actions.length)
			{
				actions.pop().detruire();
			}
			actions = null;
			sur(null);
			_etat = null;
			_largeur = NaN;
			_hauteur = NaN;
			ed = null;
		}
		
		/**
		 * Ajoute ou enlève des filtres pré-paramétrés
		 * @param	...filtres
		 */
		public function filtrer(...filtres):void
		{
			var f:Array = [];
			for (var i:int = 0; i < filtres.length; i++) 
			{
				switch (filtres[i].toLowerCase()) 
				{
					case "ombre":
						f.push(new DropShadowFilter(4,45,0x000000,0.8,6,2));
					break;
					case "creux":
						f.push(new GradientBevelFilter(4, 45, [0xFFFFFF, 0], [0.2, 0.2], [0, 255], 3, 3, 2));
					break;
					case "relief":
						f.push(new GradientBevelFilter(4, 45, [0, 0xFFFFFF], [0.2, 0.2], [0, 255], 3, 3, 2));
					break;
					default:
				}
			}
			ed.filters = f;
		}
		
		/**
		 * Ajoute une action à la liste des actions du visuel
		 * @param	a	action à gérer
		 */
		public function gerer(a:Action):void
		{
			if (actions.indexOf(a) == -1)
			{
				actions.push(a);
			}
		}
		
		/**
		 * Met l'objet (et ses ancêtres) au premier plan
		 */
		public function mettreDevant():void
		{
			var pere:DisplayObjectContainer = ed.parent;
			var enfant:DisplayObject = ed as DisplayObject;
			while (pere != null && enfant != null)
			{
				pere.addChild(enfant);
				enfant = DisplayObject(pere);
				pere = DisplayObjectContainer(enfant.parent);
			}
		}
		
		/**
		 * Met l'objet en bas de sa liste d'affichage
		 */
		public function mettreDerriere():void
		{
			var pere:DisplayObjectContainer = ed.parent;
			if (pere != null)
			{
				pere.addChildAt(ed, 0);
			}
		}
		
		/**
		 * Définit la position
		 * @param	x	gauche du visuel
		 * @param	y	haut du visuel
		 */
		public function placer(x:Number, y:Number):void
		{
			gauche = x;
			haut = y;
		}
		
		/**
		 * Définit la position de fin
		 * @param	x	droite du visuel
		 * @param	y	bas du visuel
		 */
		public function pousser(x:Number, y:Number):void
		{
			droite = x;
			bas = y;
		}
		
		/**
		 * Définir le parent
		 * @param	c	conteneur
		 */
		public function sur(c:DisplayObjectContainer, px:Number = NaN, py:Number = NaN):void
		{
			if (c == null)
			{
				if (pere != null)
					pere.adopter(this, false);
					
				if (ed.parent != null)
					ed.parent.removeChild(ed);
					
				return;
			}
			c.addChild(ed);
			if (!isNaN(py))
				placer(px, py);
		}
		
		/**
		 * Définit la taille du visuel
		 * @param	l	largeur du visuel
		 * @param	h	hauteur du visuel
		 */
		public function tailler(l:Number, h:Number):void
		{
			largeur = l;
			hauteur = h;
		}
		
		public function toString():String
		{
			return id;
		}
		
		/**
		 * Élément réactif
		 */
		public function get diffuseur():InteractiveObject
		{
			return ed;
		}
		
		public function get etat():Etat
		{
			return _etat;
		}
		
		/**
		 * Rectangle sur son parent
		 * @return
		 */
		public function get rect():Rectangle
		{
			if (ed.parent)
			{
				return ed.getRect(ed.parent);
			}
			else
			{
				return new Rectangle(ed.x, ed.y, _largeur, _hauteur);
			}
		}
		
		/**
		 * Rectangle sur la scène
		 * @return
		 */
		public function get rectScene():Rectangle
		{
			if (ed.stage)
			{
				return ed.getRect(ed.stage);
			}
			else
			{
				return new Rectangle(ed.x, ed.y, _largeur, _hauteur);
			}
		}
		
		public function set etat(value:Etat):void
		{
			if (_etat != value)
			{
				_etat = value;
				actualiser();
			}
		}
		
		/**
		 * Souris horizontale sur ed
		 */
		public function get sourisX():Number
		{
			return ed.mouseX;
		}
		
		/**
		 * Souris verticale sur ed
		 */
		public function get sourisY():Number
		{
			return ed.mouseY;
		}
		
		/**
		 * Souris horizontale sur scène
		 */
		public function get sceneX():Number
		{
			return ed.stage.mouseX;
		}
		
		/**
		 * Souris verticale sur scène
		 */
		public function get sceneY():Number
		{
			return ed.stage.mouseY;
		}
		
		/**
		 * Identifiant
		 */
		public function get id():String
		{
			return ed.name;
		}
		
		public function set id(value:String):void
		{
			ed.name = value;
		}
		
		/**
		 * Position de la gauche sur le parent en pixels
		 */
		public function get gauche():Number
		{
			return ed.x;
		}
		
		public function set gauche(value:Number):void
		{
			ed.x = value;
		}
		
		/**
		 * Position du haut sur le parent en pixels
		 */
		public function get haut():Number
		{
			return ed.y;
		}
		
		public function set haut(value:Number):void
		{
			ed.y = value;
		}
		
		/**
		 * Milieu horizontal sur le parent en pixels
		 */
		public function get centreX():Number
		{
			return ed.x + (_largeur / 2);
		}
		
		public function set centreX(value:Number):void
		{
			ed.x = value - (_largeur / 2);
		}
		
		/**
		 * Milieu vertical sur le parent en pixels
		 */
		public function get centreY():Number
		{
			return ed.y + (_hauteur / 2);
		}
		
		public function set centreY(value:Number):void
		{
			ed.y = value - (_hauteur / 2);
		}
		
		/**
		 * Droite du visuel sur le parent en pixels
		 */
		public function get droite():Number
		{
			return ed.x + _largeur;
		}
		
		public function set droite(value:Number):void
		{
			ed.x = value - _largeur;
		}
		
		/**
		 * Bas du visuel sur le parent en pixels
		 */
		public function get bas():Number
		{
			return ed.y + _hauteur;
		}
		
		public function set bas(value:Number):void
		{
			ed.y = value - _hauteur;
		}
		
		/**
		 * Largeur en pixels du visuel
		 */
		public function get largeur():Number
		{
			return _largeur;
		}
		
		public function set largeur(value:Number):void
		{
			if (value != _largeur)
			{
				_largeur = value;
				actualiser();
			}
		}
		
		/**
		 * Hauteur en pixels du visuel
		 */
		public function get hauteur():Number
		{
			return _hauteur;
		}
		
		public function set hauteur(value:Number):void
		{
			if (value != _hauteur)
			{
				_hauteur = value;
				actualiser();
			}
		}
		
		/**
		 * Moitié de la largeur
		 */
		public function get milieuX():Number
		{
			return _largeur / 2;
		}
		
		/**
		 * Moitié de la hauteur
		 */
		public function get milieuY():Number
		{
			return _hauteur / 2;
		}
		
		/**
		 * Visuel parent (ou null)
		 */
		public function get pere():Visuel
		{
			return _pere;
		}
		
		public function set pere(value:Visuel):void
		{
			_pere = value;
		}
	}
}